<template>
    <div ref="chat-room" class="chat-room">
        <van-nav-bar
                title="socket.io聊天室"
                left-text="退出"
                :right-text="`在线:${onlineNum}`"
                left-arrow
                @click-left="$router.back()"
        />
        <div class="message-list-wrap">
            <div class="message-list">
                <van-cell
                        v-for="(message, index) in messageList"
                        :key="index"
                        :border="false"
                        class="message-item"
                        :class="{ me: message.name === myName }"
                >
                    <div class="speak-name">
                        {{ message.name }}
                    </div>
                    <div class="message-con">
                        {{ message.value }}
                    </div>
                </van-cell>
            </div>
        </div>
        <div class="chat-input-wrap">
            <van-field
                    v-model.trim="inputMessage"
                    type="textarea"
                    rows="6"
                    maxlength="200"
                    placeholder="请输入要说的话按 shift+entry 发送"
                    @keyup.shift.enter="sendMessage"
            />
            <van-button
                    block
                    class="send-btn"
                    color="linear-gradient(to right, #7647e7, #623f90)"
                    @click="sendMessage"
            >
                Send
            </van-button>
        </div>
        <van-popup v-model="nameInputShow" round :close-on-click-overlay="false">
            <div class="popup-con">
                <van-field
                        v-model.trim="myName"
                        label="昵称"
                        maxlength="3"
                        placeholder="请输入昵称"
                />
                <van-button
                        block
                        round
                        color="linear-gradient(to right, #7647e7, #623f90)"
                        @click="submitName"
                >
                    确定
                </van-button>
            </div>
        </van-popup>
    </div>
</template>

<script>
// 使用vant 组件
import {
  List,
  NoticeBar,
  Cell,
  CellGroup,
  Button,
  Field,
  Popup,
  NavBar,
} from 'vant'
import io from 'socket.io-client'

import BScroll from 'better-scroll'

export default {
  name: 'Chat',
  components: {
    [List.name]: List,
    [CellGroup.name]: CellGroup,
    [Cell.name]: Cell,
    [NoticeBar.name]: NoticeBar,
    [Field.name]: Field,
    [Popup.name]: Popup,
    [NavBar.name]: NavBar,
    [Button.name]: Button
  },
  data() {
    return {
      id: '',
      ws: null,
      socket: null,
      // 在线人数
      onlineNum: 0,
      scroll: null,
      messageList: [],
      inputMessage: '',
      nameInputShow: false,
      myName: ''
    }
  },
  watch: {
    messageList() {
      this.$nextTick(() => {
        this.scroll.refresh()
        this.scroll.scrollTo(0, this.scroll.maxScrollY)
      })
    }
  },
  created() {
    if (window.localStorage.getItem('messageList')) {
      this.messageList = JSON.parse(window.localStorage.getItem('messageList'))
    }
    this.initSocket()
  },
  destroyed() {
    this.socket.close()
  },
  mounted() {
    // eslint-disable-next-line no-unused-vars
    this.scroll = new BScroll(document.querySelector('.message-list-wrap'), {
      scrollY: true,
      click: true,
      mouseWheel: true
    })
    if (window.localStorage.getItem('myName')) {
      this.myName = window.localStorage.getItem('myName')
      this.nameInputShow = false
    } else {
      this.nameInputShow = true
    }
  },
  methods: {
    receiveMsg(msgData) {
      const msg = JSON.parse(msgData)
      if (msg.type === 'login') {
        this.$toast(`${msg.data}进入了聊天室`)
      } else {
        this.messageList.push(msg)
        if (this.messageList.length > 100) {
          this.messageList = this.messageList.slice(-100)
        }
        window.localStorage.setItem(
          'messageList',
          JSON.stringify(this.messageList)
        )
      }
    },
    sendMessage() {
      if (this.inputMessage) {
        let sendData = { name: this.myName, value: this.inputMessage }
        this.socket.emit('msg', JSON.stringify(sendData))
        this.inputMessage = ''
      } else {
        this.$toast('不能发送空白消息')
      }
    },
    submitName() {
      if (this.myName) {
        window.localStorage.setItem('myName', this.myName)
        this.nameInputShow = false
        this.socket.emit('addUser', this.myName)
      } else {
        this.$toast('请输入昵称')
      }
    },
    getAtName(str) {
      // eslint-disable-next-line no-useless-escape
      const index = str.lastIndexOf('\@')
      str = str.substring(index + 1, index + 4)
      return str
    },
    getUserName() {
      if (window.localStorage.getItem('myName')) {
        return window.localStorage.getItem('myName')
      } else {
        return null
      }
    },
    initSocket() {
      const socket = io(process.env.VUE_APP_SOCKETIO)
      // const socket = io('')

      this.socket = socket
      this.socket.on('open', () => {
        this.$toast('socket io is open !')
      })

      this.socket.on('connect', () => {
        if (this.getUserName() !== null) {
          // 推送用户账号给后端socket
          socket.emit('addUser', this.getUserName())
        }
      })
      this.socket.on('close', () => {
        console.log('socket连接关闭')
      })
      /* Listeners 用户上线信息 */
      this.socket.on('online', data => {
        console.log('online：socket', data)
        // 触发当前实例上的事件。data传给监听器回调。
        this.$toast(`${data}上线了`)
      })

      /* Listeners 用户下线信息 */
      this.socket.on('offline', data => {
        this.$toast(`${data}下线了`)
      })

      /* Listeners 广播信息 */
      this.socket.on('broadcastMsg', data => {
        this.receiveMsg(data)
      })

      /* Listeners  在线人数 */
      this.socket.on('clientNum', data => {
        this.onlineNum = data
      })

      /* Listeners  连接失败 */
      this.socket.on('disconnect', data => {
        console.log(data)
      })
    }
  }
}
</script>

<style scoped lang="less">
    .chat-room {
        min-height: 100vh;
        background-color: #f1f3f5;

        .message-list-wrap {
            box-sizing: border-box;
            height: calc(100vh - 46PX - 408px);
            overflow: hidden;
        }

        .speak-name {
            position: absolute;
            top: 0;
            left: 0;
            box-sizing: border-box;
            display: block;
            width: 40px;
            height: 40px;
            overflow: hidden;
            font-size: 12px;
            font-weight: bold;
            line-height: 40px;
            color: #333333;
            text-align: center;
            background-color: #cccccc;
            border-radius: 50%;
        }

        .message-con {
            position: relative;
            display: inline-block;
            min-height: 24px;
            padding: 10px;
            word-break: break-all;
            word-wrap: break-word;
            background-color: #ffffff;
            border-radius: 6px;

            &::before {
                position: absolute;
                top: 10px;
                left: -7px;
                display: block;
                width: 0;
                height: 0;
                content: '';
                border-top: 6px solid transparent;
                border-right: 8px solid white;
                border-bottom: 6px solid transparent;
            }

            &::after {
                display: none;
            }
        }

        /deep/ .message-item {
            position: relative;
            padding: 2.667vw 2.267vw;
            margin-bottom: 10px;
            background-color: transparent;

            &:last-child {
                margin-bottom: 0;
            }

            .van-cell__value {
                padding: 0 50px;
            }

            &.me {
                .speak-name {
                    position: absolute;
                    top: 0;
                    right: 0;
                    left: auto;
                }

                .message-con {
                    float: right;
                    background-color: #9eea6a;

                    &::before {
                        display: none;
                    }

                    &::after {
                        position: absolute;
                        top: 10px;
                        right: -7px;
                        display: block;
                        width: 0;
                        height: 0;
                        content: '';
                        border-top: 6px solid transparent;
                        border-bottom: 6px solid transparent;
                        border-left: 8px solid #9eea6a;
                    }
                }
            }
        }

        .chat-input-wrap {
            position: fixed;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 408px;
            border-top: 1px solid #cac9c9;
        }

        .chat-input {
            box-sizing: border-box;
            display: block;
            width: 100%;
            padding: 10px;
            background-color: #e5e4e3;
            border: none;
        }

        .popup-con {
            width: 580px;
            padding: 20px;

            /deep/ .van-field__label {
                width: 100px;
            }
        }
    }
</style>
